﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Collections.ObjectModel;
using System.Collections.Generic;

namespace BattleforgeAssault.Cards
{

    /// <summary>
    /// Right now this is just a test deck with a ton of copies of a few dwarf cards.
    /// Eventually, this might be one of each dwarf card.
    /// </summary>
    public class DwarfCards : List<Card>
    {
        public DwarfCards()
        {
            for (int i = 0; i < 38; ++i)
            {
                this.Add(new Card_1_1());
            }
            for (int i = 0; i < 3; ++i)
            {
                this.Add(new Card_1_1());
                this.Add(new Card_1_13());
                this.Add(new Card_1_17());
                this.Add(new Card_1_19());
            }
        }
    }

    public class Card_1_1 : Unit
    {
        public Card_1_1()
        {
            Power = 1;
            HitPoints = 1;
            Cost = 1;
            Race = Types.Races.Dwarf;
            Loyalty = 1;
            Number = 1;
            Title = "Defender of the Hold";
            Text = "Battlefield Only.";
            FlavorText = "My blood for the hold, 'tis a fair trade.";
            Traits.Add(Types.Traits.Warrior);
            Keywords.Add(Types.Keywords.BattlefieldOnly);
        }
    } // Card_1_1 class

    public class Card_1_2 : Unit  // TODO: Effect
    {
        public Card_1_2()
        {
            Power = 1;
            HitPoints = 3;
            Cost = 3;
            Controller = this.Game.ActivePlayer;
            Owner = this.Game.ActivePlayer;
            Race = Types.Races.Dwarf;
            Loyalty = 1;
            Number = 1;
            Title = "Zhufbar Engineers";
            Text = "Forced: When this unit leaves play, each opponent must sacrifice a unit in this corresponding zone.";
            Traits.Add(Types.Traits.Engineer);
            Effects.Add(new Effect_1_2() { Source = this });
        }
        class Effect_1_2 : Effect
        {
            public Effect_1_2() { Trigger = "PostLeavePlay"; }

            public override bool Applicable(GameObject sender)
            {
                return true;
            }

            public override void Apply(GameObject sender)
            {
                Player controller = (Source as Card).Controller;
                //how do I get the zone the card is located in?
                Location zone = (Source as Card).Location;  
                Messager.SendMessage("Each opponent must sacrifice a unit in his {0} zone.", zone);

                foreach (var player in controller.Opponents) //the following is mostly prosciutto code
                {
                    var targets = player.SelectTargets("Sacrifice a unit in your corresponding zone", 1, 1,
                        (t) => { return (t is Card && ((Card)t) is Unit && ((Card)t).Controller == player && ((Card)t).Location == zone); });
                    foreach (var target in targets)
                    {
                        ((Card)target).Sacrifice();
                    }
                }
            }
        }
    } // Card_1_2 class

    public class Card_1_3 : Unit
    {
        public Card_1_3()
        {
            Power = 1;
            HitPoints = 2;
            Cost = 2;
            Controller = this.Game.ActivePlayer;
            Owner = this.Game.ActivePlayer;
            Race = Types.Races.Dwarf;
            Loyalty = 1;
            Number = 3;
            Title = "Hammerer of Karak Azul";
            Text = "Toughness 1 (whenever this unit is assigned damage, cancel 1 of that damage).";
            FlavorText = "";
            Traits.Add(Types.Traits.Warrior);
            Traits.Add(Types.Traits.Elite);
            Keywords.Add(Types.Keywords.Toughness);  //he has toughness 1, but I dont know how that is handled
            Effects.Add(new ToughnessEffect() { Source = this, });
        }
        class ToughnessEffect : Modifier //TODO: un-break this
        {
            private int _value = 1;
            public int Value
            {
                get { return _value; }
                set { _value = value; }
            }
            
            public ToughnessEffect() { Trigger = "DamageAssigned"; }

            public override bool Applicable(GameObject sender)
            {
                var game = source.Game;
                var target = sender as Unit;

                return true;
            }

            public override int Modify(int value)
            {
                if (value > 0) { return value - _value; }
                return value;
            }
        }
    } // Card_1_3 class

    public class Card_1_13 : Support
    {
        public Card_1_13()
        {
            Cost = 2;
            Race = Types.Races.Dwarf;
            Loyalty = 1;
            Number = 13;
            Title = "Rune of Fortitude";
            Text = "Each unit attacking this zone loses 1 power unless its controller pays 1 resource per unit.";
            Traits.Add(Types.Traits.Rune);

            Effects.Add(new Effect_1_13() { Source = this });
        }

        class Effect_1_13 : Modifier
        {
            public Effect_1_13() { Trigger = "Power"; }

            public override bool Applicable(GameObject sender)
            {
                var source = Source as Support;
                var game = source.Game;
                var target = sender as Unit;

                return (game.Phase == Types.Phases.Battlefield && game.CurrentAttackers.Contains(target) && game.CurrentAttackedZone == source.Location);
            }

            public override int Modify(int value)
            {
                if (value > 0) { return value - 1; }
                return value;
            }
        } // Effect_1_13 class
    } // Card_1_13 class

    public class Card_1_17 : Quest
    {
        public Card_1_17()
        {
            Race = Types.Races.Dwarf;
            Loyalty = 2;
            Number = 17;
            Title = "A Glorious Death";
            Text = "Quest. Action: Sacrifice the unit on this quest to destroy up to two target attacking units. Use this ability only if A Glorious Death has 3 or more resource tokens on it." + Environment.NewLine +
            "Quest. Forced: Place 1 resource token on this card at the beginning of your turn if a unit is questing here.";

            Action = new Action_1_17() { Source = this };
            Effects.Add(new AddTokenToQuest() { Source = this });
        }

        class Action_1_17 : Action
        {
            private bool IsValidTarget(GameObject target)
            {
                Card source = this.Source as Card;

                return (target is Unit && source.Game.CurrentAttackers.Contains((Unit)target));
            }

            public override bool Applicable(GameObject sender)
            {
                Quest quest = this.Source as Quest;

                return (sender == this.Source && quest.Questing != null && quest.Tokens >= 3 && quest.Game.Phase == Types.Phases.Battlefield && quest.Game.CurrentAttackers.Count > 0);
            }

            public override bool DeclareTargets()
            {
                Card source = this.Source as Card;
                Player controller = source.Controller;

                var targets = controller.SelectTargets("Choose up to two attackers", 0, 2, IsValidTarget);

                if (targets.Count > 0)
                {
                    foreach (var target in targets) { Targets.Add(target); }
                    return true;
                }
                return false;
            }

            public override bool PayCosts()
            {
                Card source = this.Source as Card;
                Player controller = source.Controller;

                if (source.Tokens >= 3)
                {
                    source.Destroy();
                    source.Tokens = 0;
                    return true;
                }

                return false;
            }

            public override void Apply(GameObject sender)
            {
                foreach (var target in Targets)
                {
                    if (IsValidTarget(target)) { ((Unit)target).Destroy(); }
                }
            }
        } // Action_1_17 class
    } // Card_1_17 class

    public class Card_1_19 : Tactic
    {
        public Card_1_19()
        {
            Race = Types.Races.Dwarf;
            Loyalty = 2;
            Number = 19;
            Title = "Burying the Grudge";
            Text = "Action: Gain 1 resource for each unit that entered a discard pile this turn.";
            FlavorText = "Grudges are best buried with the corpse of the wrongdoer.";

            Action = new Action_1_19() { Source = this };
        }

        private class Action_1_19 : Action
        {
            public override bool Applicable(GameObject sender)
            {
                return true;
            }

            public override bool PayCosts()
            {
                Card card = Source as Card;
                return true;
            }

            public override void Apply(GameObject sender)
            {
                Messager.SendMessage("Applying {0} effect", Source);
                Player controller = (Source as Card).Controller;
                Game game = (Source as Card).Game;
                int resourcesGained = 0;
                foreach (var card in controller.Discard.Cards)
                {
                    if (card is Unit && card.TurnLeftPlay == game.Turn) { resourcesGained++; }
                }
                if (resourcesGained > 0)
                {
                    controller.Resources += resourcesGained;
                    Messager.SendMessage("{0} received {1} resources from {2}", controller, resourcesGained, this);
                }
            }
        } // Action_1_19 class
    } // Card_1_19 class
} // namespace 
